#pragma once

#include "MODELOBJDef.h"
#include "CGALDefinition.h"
#include <CGAL/minkowski_sum_3.h>

#ifdef MYLIB_API_EXPORT
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif

class MYLIB_API CMorphologicalProc
{
private:
	typedef CGAL::Polyhedron_3<EK, My_items> EK_Poly_3;
	typedef EK::Vector_3 Vector_3;

public:
	CMorphologicalProc(void);
	~CMorphologicalProc(void);

	static CMorphologicalProc* GetSingleton()
	{
		if (NULL == _instance.get())
		{
			_instance.reset(new CMorphologicalProc);
		}
		return _instance.get();
	}
protected:
	static std::auto_ptr<CMorphologicalProc> _instance;

private:
	//extend the size of a AABB Box
	void ExtentRange(double& Min,double& Max,double scale);
	
	//Calculate the AABB bounding box of a object
	void CalBoundingBox(const EK_Poly_3* pSolid, EK_Poly_3& poly, double scale);

	//Generate a Cube
	void GenPoly(double size, EK_Poly_3& poly);

public:

	//have to free the memory
	Nef_polyhedron_3* MinKowskisum(Nef_polyhedron_3* poly, double operSize = 1.0);
	//
	bool MinKowskisum(ModelOBJ* model,double operSize = 1.0);

	//have to free the memory
	Nef_polyhedron_3* ReversMinKowskisum(Nef_polyhedron_3* poly, double operSize = 1.0);
	//
	bool ReversMinKowskisum(ModelOBJ* model, double operSize = 1.0);

	//Closing
	bool minkowski_closing(ModelOBJ* model, double operSize = 1.0);
	//
	void minkowski_closing(Nef_polyhedron_3* poly, double operSize = 1.0);

	//Opening
	bool minkowski_opening(ModelOBJ* model, double operSize = 1.0);
	//
	void minkowski_opening(Nef_polyhedron_3* poly, double operSize = 1.0);

};
